Подключим Keras и все необходимые нам модули
In [2]:
import keras
from keras import applications
from keras.utils.vis_utils import model_to_dot
from keras.applications import imagenet_utils
from keras import backend as K
import numpy as np
import tensorflow as tf
In [3]:
from skimage.transform import resize
In [4]:
from imageio import imread, imwrite
In [5]:
sess = K.get_session()
sess.as_default()
Out[5]:
In [6]:
import matplotlib.pyplot as plt
# plt.style.use('ggplot')
%matplotlib inline
plt.rcParams['figure.figsize'] = (20,10) # set default size of plots
В модуле applications вы сможете найти большое количество предтренированных моделей. Загрузим уже знакомый нам VGG16, обученный на Imagenet
In [7]:
# build the VGG16 network
K.clear_session()
model = applications.VGG16(include_top=True,
weights='imagenet')
В Keras существуют удобные средства для визуализации моделей.
In [8]:
model.summary()
In [9]:
image = imread('image_1.jpg')
In [10]:
plt.imshow(image)
Out[10]:
In [11]:
resized_image = resize(image, (224, 224), mode='wrap', preserve_range=True)
y = model.predict(np.expand_dims(resized_image, 0))
In [12]:
model.input
Out[12]:
In [13]:
imagenet_utils.decode_predictions(y)
Out[13]:
In [14]:
def build_train_function(class_index = 0):
# Получаем тензор, отвечающий за вход модели
input_img = model.input
# Выберем нужный слой
predictions = model.output
probabilities = K.softmax(predictions)
objective = K.log(probabilities + 1e-8)[:,class_index]
# Вызываем метод бэкенда, рассчитывающий градиент
grads = K.gradients(objective, input_img)[0]
# Оборачиваем всё это в специальную абстракцию,
# которая скрывает вызов сессии TF
return K.function([input_img], [grads, objective])
In [15]:
def deprocess_image(x):
x -= x.mean()
x /= (x.std() + 1e-5)
x *= 0.1
# clip to [0, 1]
x += 0.5
x = np.clip(x, 0, 1)
# convert to RGB array
x *= 255
x = np.clip(x, 0, 255).astype('uint8')
return x
In [15]:
def compute_image(train_function, img, max_iter = 50, lr = 1, epsilon = 5.0):
input_img_data = img.copy()
below = img - epsilon
above = img + epsilon
for i in range(max_iter):
grads_value, objective_value = train_function([input_img_data])
grads_value /= grads_value.std()+1e-8
input_img_data += grads_value * lr
input_img_data = np.clip(np.clip(input_img_data, below, above), 0, 255)
print(f'objective: {np.mean(objective_value):.2}', end='\r')
input_img_data = input_img_data[0]
return input_img_data.astype(np.uint8)
# return deprocess_image(input_img_data)
In [16]:
plt.imshow(resized_image.astype(np.uint8))
Out[16]:
In [17]:
train_function = build_train_function(965)
img = compute_image(train_function, lr=1, img= np.expand_dims(resized_image, 0), epsilon=3.0)
plt.imshow(img)
Out[17]:
In [18]:
y = model.predict(np.expand_dims(img, 0))
imagenet_utils.decode_predictions(y)
Out[18]:
In [19]:
from scipy.ndimage.interpolation import shift, rotate
In [20]:
rotated = rotate(img, np.degrees(np.pi/8), reshape=False)
In [21]:
plt.imshow(rotated)
Out[21]:
In [23]:
y = model.predict(np.expand_dims(rotated, 0))
imagenet_utils.decode_predictions(y)
Out[23]:
In [24]:
model.input
Out[24]:
In [25]:
def build_train_function_robust(class_index = 0, num_samples = 20):
# Получаем тензор, отвечающий за вход модели
input_img = K.placeholder(shape=(1, 224,224,3))
# Выберем нужный слой
# predictions = layer_dict['predictions'].output
# probabilities = K.softmax(predictions)
objectives = []
for _ in range(num_samples):
angle = K.random_uniform((), minval=-np.pi/4, maxval=np.pi/4)
rotated = tf.contrib.image.rotate(input_img, angles=angle)
output = model(rotated)
probabilities = K.softmax(output)
neg_xent = K.log(probabilities + 1e-8)[:,class_index]
objectives.append(neg_xent)
objective = K.mean(neg_xent)
# Вызываем метод бэкенда, рассчитывающий градиент
grads = K.gradients(objective, input_img)[0]
# Оборачиваем всё это в специальную абстракцию,
# которая скрывает вызов сессии TF
return K.function([input_img], [grads, objective])
In [26]:
train_function = build_train_function_robust(965)
img = compute_image(train_function, lr=1, img= np.expand_dims(resized_image, 0), epsilon=3.5)
plt.imshow(img)
Out[26]:
In [27]:
y = model.predict(np.expand_dims(img, 0))
imagenet_utils.decode_predictions(y)
Out[27]:
In [28]:
rotated = rotate(img, - np.degrees(np.pi/8), reshape=False)
plt.imshow(rotated)
Out[28]:
In [29]:
y = model.predict(np.expand_dims(rotated, 0))
imagenet_utils.decode_predictions(y)
Out[29]:
In [ ]: